package org.jeecg.modules.demo.crm.glm.util;


import net.coobird.thumbnailator.Thumbnails;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecg.common.util.MinioUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class ConvertRemoteFileToImageUtils {

    private static final RestTemplate REST = new RestTemplate();

    /**
     * 入口：传入 http/https 地址，返回图片列表
     */
    public static List<BufferedImage> convert(String fileUrl) throws IOException {
        // 1. 拉取文件
        ResponseEntity<byte[]> resp = REST.getForEntity(fileUrl, byte[].class);
        byte[] bytes = resp.getBody();
        if (bytes == null || bytes.length == 0) {
            throw new IOException("下载文件为空");
        }
        String lower = fileUrl.toLowerCase();
        try (InputStream in = new ByteArrayInputStream(bytes)) {
            if (lower.endsWith(".pdf")) {
                return pdfToImage(in);
            } else if (lower.endsWith(".xls") || lower.endsWith(".xlsx")) {
                return excelToImage(in);
            } else if (lower.endsWith(".jpg") || lower.endsWith(".jpeg") || lower.endsWith(".png")) {
                return rasterToImage(in);
            } else {
                throw new IOException("暂不支持的文件类型");
            }
        }
    }

    /* ---------- PDF ---------- */
    private static List<BufferedImage> pdfToImage(InputStream in) throws IOException {
        List<BufferedImage> list = new ArrayList<>();
        try (PDDocument doc = PDDocument.load(in)) {
            PDFRenderer renderer = new PDFRenderer(doc);
            int pages = doc.getNumberOfPages();
            for (int i = 0; i < pages; i++) {
                BufferedImage img = renderer.renderImageWithDPI(i, 144); // 144 DPI 足够清晰
                list.add(img);
            }
        }
        return list;
    }

    /* ---------- Excel ---------- */
    private static List<BufferedImage> excelToImage(InputStream in) throws IOException {
        Workbook wb = org.apache.poi.ss.usermodel.WorkbookFactory.create(in);
        List<BufferedImage> list = new ArrayList<>();
        for (int s = 0; s < wb.getNumberOfSheets(); s++) {
            Sheet sheet = wb.getSheetAt(s);
            // 简易策略：把 sheet 画成一张大图
            BufferedImage img = renderSheet(sheet);
            if (img != null) list.add(img);
        }
        wb.close();
        return list;
    }

    private static BufferedImage renderSheet(Sheet sheet) {
        // 1. 计算总行数/列数
        int lastRow = sheet.getLastRowNum();
        int maxCol = 0;
        for (int i = 0; i <= lastRow; i++) {
            Row r = sheet.getRow(i);
            if (r != null) maxCol = Math.max(maxCol, r.getLastCellNum());
        }
        if (maxCol == 0) return null;

        // 2. 单元格尺寸按 32px 行高 256px 列宽估算
        int cellW = 256, cellH = 32;
        int imgW = cellW * maxCol;
        int imgH = cellH * (lastRow + 1);
        BufferedImage img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, imgW, imgH);
        g2.setColor(Color.BLACK);
        g2.setFont(new Font("Consolas", Font.PLAIN, 16));

        // 3. 画单元格
        for (int rIdx = 0; rIdx <= lastRow; rIdx++) {
            Row row = sheet.getRow(rIdx);
            if (row == null) continue;
            for (int cIdx = 0; cIdx < maxCol; cIdx++) {
                Cell cell = row.getCell(cIdx, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
                String txt = "";
                if (cell != null) {
                    cell.setCellType(CellType.STRING);
                    txt = cell.getStringCellValue();
                }
                g2.drawString(txt, cIdx * cellW + 5, rIdx * cellH + 20);
            }
        }
        g2.dispose();
        return img;
    }

    /* ---------- JPG/PNG ---------- */
    private static List<BufferedImage> rasterToImage(InputStream in) throws IOException {
        BufferedImage src = ImageIO.read(in);
        if (src == null) throw new IOException("无法解析图片");
        // 可选：等比缩放到最大 2048 宽
        if (src.getWidth() > 2048) {
            src = Thumbnails.of(src).width(2048).keepAspectRatio(true).asBufferedImage();
        }
        List<BufferedImage> list = new ArrayList<>();
        list.add(src);
        return list;
    }

    /* ---------- 工具：把 BufferedImage 转 byte[] ---------- */
    public static String toPngBytes(BufferedImage img) throws IOException {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ImageIO.write(img, "PNG", out);
            String bizPath = "temp";
            String originalFilename = "page_" + (0 + 1) + ".png";
            MultipartFile multipartFile = new PdfToImageUploader.CustomMultipartFile(
                    "file",           // field name for the file, often "file"
                    originalFilename, // original file name
                    "image/png",      // content type
                    out.toByteArray()        // file content as byte array
            );
            String uploadedUrl = MinioUtil.upload(multipartFile, bizPath);
            return uploadedUrl;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws IOException {

        List<BufferedImage> imgs = ConvertRemoteFileToImageUtils
                .convert("https://xxx.com/file/test.pdf");
        String url = ConvertRemoteFileToImageUtils.toPngBytes(imgs.get(0));

       // String url = ossService.upload("pdf/page_" + (i + 1) + ".png", png);
    }
}